package com.foohoo.benchmark.string;

import lombok.extern.slf4j.Slf4j;
import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.infra.Blackhole;

import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;

/**
 * 测试不同的字符串搜索方式的性能
 * Benchmark                      Mode  Cnt   Score    Error  Units
 * StringSearch.searchByContains  avgt    3   9.184 ±  1.465  ns/op
 * StringSearch.searchByIndexOf   avgt    3   9.151 ±  8.679  ns/op
 * StringSearch.searchByPattern   avgt    3  61.247 ± 61.863  ns/op
 * 一句话结论: 正则表达式非常慢，慎用;contains其实就是对indexOf的包装，如果只是判断是否存在首选该方法
 *
 * @author mzdbxqh
 * @date 2020-10-20 13:35
 **/
@Slf4j
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Warmup(iterations = 5, time = 1)
@Measurement(iterations = 3, time = 1)
@Fork(1)
@Threads(1)
@State(Scope.Benchmark)
public class StringSearch {

	private static final String SOURCE_STRING = "hello world";

	private static final String QUERY_STRING = "l";

	private static final Pattern PATTERN = Pattern.compile(QUERY_STRING);

	@Benchmark
	public void searchByIndexOf(Blackhole bh) {
		boolean result = false;
		if (SOURCE_STRING.indexOf(QUERY_STRING) >= 0) {
			result = true;
		}
		bh.consume(result);
	}

	@Benchmark
	public void searchByContains(Blackhole bh) {
		boolean result = false;
		if (SOURCE_STRING.contains(QUERY_STRING)) {
			result = true;
		}
		bh.consume(result);
	}

	@Benchmark
	public void searchByPattern(Blackhole bh) {
		boolean result = false;
		if (PATTERN.matcher(QUERY_STRING).find()) {
			result = true;
		}
		bh.consume(result);
	}
}
